#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
"""
@File    :   onecloud.py
@Time    :   2024-04-21 14:57
@Author  :   坐公交也用券
@Version :   1.0
@Contact :   faith01238@hotmail.com
@Homepage : https://liumou.site
@Desc    :   在玩客云的armbian系统上部署TT服务、 DDNS服务、配置系统环境等
"""
import logging
import os
import subprocess
import sys
from argparse import ArgumentParser
from os import path
from shutil import copy2

# 创建一个自定义的日志记录器
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# 创建一个自定义的日志处理器，设置其输出格式
formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(filename)s:%(lineno)d | %(funcName)s | %(message)s')
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(formatter)
logger.addHandler(handler)


class InstallOnecloud:
	def __init__(self, url, name: str):
		"""

		:param url:
		:param name:
		"""
		self.url = url
		self.name = name

	def sources(self):
		"""
		配置源
		:return:
		"""
		if var_source:
			logger.info("取消源配置")
			return
		logger.info("正在配置源...")
		if not path.isfile("/etc/apt/sources.list.bak"):
			try:
				copy2("/etc/apt/sources.list", "/etc/apt/sources.list.bak")
			except Exception as e:
				print(e)
		try:
			logger.debug("配置源")
			with open("/etc/apt/sources.list", "w", encoding='utf8') as f:
				f.write("""deb https://mirrors.ustc.edu.cn/debian buster main contrib non-free                                                                                                       
deb https://mirrors.ustc.edu.cn/debian buster-updates main contrib non-free                                                                                               
#deb https://mirrors.ustc.edu.cn/debian buster-backports main contrib non-free                                                                                             
deb https://mirrors.ustc.edu.cn/debian-security/ buster/updates main contrib non-free """)
		except Exception as e:
			logger.error(f"无法写入源配置: {e}")
			sys.exit(2)
		if os.system(f"apt update") == 0:
			logger.info("源配置成功")
		else:
			logger.warning("源配置存在异常,可忽略...")

	def dns(self):
		"""
		配置dns
		:return:
		"""
		logger.info("正在配置dns")
		if not path.isfile("/etc/resolv.conf.bak"):
			try:
				copy2("/etc/resolv.conf", "/etc/resolv.conf.bak")
			except Exception as e:
				logger.error(e)
				sys.exit(2)
		dns = """\nnameserver 223.5.5.5
nameserver 119.29.29.29
nameserver 8.8.8.8
nameserver 223.6.6.6
nameserver 2400:3200::1
nameserver 2402:4e00::
"""
		try:
			with open("/etc/resolv.conf", mode="a+", encoding='utf8') as f:
				f.write(dns)
				f.close()
		except Exception as e:
			logger.error(f"无法写入dns配置: {e}")
			sys.exit(2)

	def install_ttnode(self):
		"""
		安装
		:return:
		"""
		logger.info("正在安装ttnode...")
		file = str(self.url).split('/')[-1]
		self.download_shell(url=self.url, file=file)
		os.system(f"python3 {file} -p -docker -b bynode -u https://down.liumou.site/ttmanager2/1.5.12/ttmanager_arm32")

	def ncat(self):
		"""
		设置端口转发
		:return:
		"""
		logger.info("正在设置端口转发...")
		if os.system("which ncat") != 0:
			logger.warning("ncat不存在,正在安装...")
			r = subprocess.getstatusoutput("apt install ncat -y")
			if r[0] != 0:
				logger.error("无法安装ncat")
				print(r[1])
				sys.exit(2)
		file = '/etc/systemd/system/com.liumou.ssh.service'
		name = 'com.liumou.ssh.service'
		txt = f"""[Unit]
Description=This is a Ncat Port Forwarding Service
After=network.target

[Service]
Type=simple
User=root
ExecStart=ncat --sh-exec "ncat 127.0.0.1 22" -l 11294 --keep-open
StandardOutput=journal
KillMode=control-group
Restart=on-failure
RestartPreventExitStatus=255
StandardError=inherit
SyslogIdentifier=com.liumou.ncat

[Install]
WantedBy=multi-user.target
Alias=com.liumou.ssh.service
"""
		try:
			with open(file, mode="w", encoding='utf8') as f:
				f.write(txt)
				os.system(f"systemctl daemon-reload")
		except Exception as e:
			logger.error(f"无法写入ncat配置: {e}")
			sys.exit(2)
		if os.system(f"systemctl start {name}") == 0:
			logger.info("ncat启动成功")
		else:
			logger.error("ncat启动失败")
		r = subprocess.getstatusoutput(f"systemctl enable {name}")
		if r[0] == 0:
			logger.info("ncat设置开机启动成功")
		else:
			logger.error("ncat设置开机启动失败")
			print(r[1])

	def install_docker(self):
		"""
		安装Docker-ce
		:return:
		"""
		if var_docker:
			logger.info("跳过Docker-ce配置")
			return
		logger.info("正在配置Docker-ce...")
		url = 'https://gitee.com/liumou_site/pvet/raw/master/model/armbian/armbian_docker.sh'
		self.download_shell(file=str(url).split("/")[-1], url=url)
		os.system(f'chmod +x armbian_docker.sh')
		os.system(f'bash ./armbian_docker.sh')

	def install_ddns(self):
		"""
		安装ddns
		:return:
		"""
		logger.info("正在安装ddns...")
		file = 'com.liumou.ddns-tencent_linux-armhf_latest.deb'
		cmd = f"wget https://down.liumou.site/client/com.liumou.ddns-tencent/{file}"
		os.system(f'rm -f {file}*')
		subprocess.getoutput("dpkg -P com.liumou.ddns-tencent")
		r = subprocess.getstatusoutput(cmd)
		if r[0] == 0:
			r = subprocess.getstatusoutput(f"dpkg -i {file}")
			if r[0] == 0:
				logger.info("ddns安装成功")
			else:
				logger.error("ddns安装失败")
				print(r[1])
				sys.exit(2)
		else:
			logger.error("无法下载脚本")
			print(r[1])
			sys.exit(2)

	def set_hostname(self):
		"""

		:return:
		"""
		logger.info(f"正在设置主机名: {self.name}")
		file = '/etc/hostname'
		try:
			with open(file, mode="w", encoding='utf8') as f:
				f.write(self.name)
		except Exception as e:
			logger.error(f"无法写入hostname配置: {e}")
			sys.exit(2)

		file = '/etc/hosts'
		try:
			with open(file, mode="a+", encoding='utf8') as f:
				f.write(f"\n127.0.0.1 {self.name}\n")
		except Exception as e:
			logger.error(f"无法写[ {file} ]配置: {e}")
			sys.exit(2)

		if os.system(f"hostname {self.name}") == 0:
			logger.info(f"hostname设置成功: {self.name}")
		else:
			logger.error(f"hostname设置失败: {self.name}")

	def set_mac(self):
		"""
		设置静态MAC
		:return:
		"""
		url = 'https://gitee.com/liumou_site/pvet/raw/master/model/armbian/mac.sh'
		filename = str(url).split('/')[-1]
		self.download_shell(file=filename, url=url)
		os.system(f'chmod +x {filename}')
		os.system(f'bash ./{filename}')

	def download_shell(self, file, url):
		"""

		:param file:
		:param url:
		:return:
		"""
		if os.system("which wget") != 0:
			r = subprocess.getstatusoutput(f"apt install wget -y")
			if r[0] != 0:
				logger.error("无法安装wget")
				print(r[1])
				sys.exit(2)
		# 开始下载
		r = subprocess.getstatusoutput(f"rm -f {file}")
		if r[0] != 0:
			logger.error(f"无法删除 {file}")
			print(r[1])
			sys.exit(2)
		r = subprocess.getstatusoutput(f'wget -O {file} {url}')
		if r[0] != 0:
			logger.error("无法下载脚本")
			print(f'wget -O {file} {url}')
			print(r[1])
			sys.exit(2)
		logger.info(f"下载成功: {url}")

	def install_pppoe(self):
		"""
		安装PPPOE
		:return:
		"""
		url = 'https://gitee.com/liumou_site/pvet/raw/master/model/armbian/pppoe.py'
		filename = str(url).split('/')[-1]
		self.download_shell(file=filename, url=url)
		# 开始执行
		os.system(f'python3 {filename}')

	def start(self):
		self.set_hostname()
		self.set_mac()
		self.dns()
		self.sources()
		# self.install_pppoe()
		self.install_docker()
		self.ncat()
		self.install_ddns()
		self.install_ttnode()


if __name__ == '__main__':
	arg = ArgumentParser(description='当前脚本版本: 1.1', prog="玩客云配置Armbian")
	h = "设置主机名称"
	arg.add_argument('-n', '--name', type=str, help=h, required=False, default="onecloud")
	arg.add_argument('-s', action='store_true', help='取消配置source源')
	arg.add_argument('-docker', action='store_true', help='取消Docker配置')
	args = arg.parse_args()
	arg_name = args.name
	var_source = args.s
	var_docker = args.docker
	up = InstallOnecloud(url='https://gitee.com/liumou_site/pvet/raw/master/model/tt/TTNODE.py', name=arg_name)
	up.start()
